#include "core/enhanced_chat_system_db.h"
#include <random>
#include <algorithm>
#include <sstream>
#include <sys/socket.h>
#include <iostream>

EnhancedChatSystemDB::EnhancedChatSystemDB() : dbManager(nullptr) {
}

EnhancedChatSystemDB::~EnhancedChatSystemDB() {
    cleanup();
}

bool EnhancedChatSystemDB::initialize(const DatabaseConfig& config) {
    // 初始化数据库管理器
    if (!initializeDatabase(config)) {
        std::cerr << "Failed to initialize database" << std::endl;
        return false;
    }
    
    dbManager = g_databaseManager.get();
    std::cout << "Enhanced chat system with database initialized successfully" << std::endl;
    return true;
}

void EnhancedChatSystemDB::cleanup() {
    // 同步在线用户状态到数据库
    syncOnlineUsersToDatabase();
    
    // 清理内存缓存
    {
        std::lock_guard<std::mutex> lock(usersMutex);
        onlineUsers.clear();
        socketToUser.clear();
    }
    
    // 清理数据库连接
    cleanupDatabase();
}

// ==================== 用户管理 ====================

bool EnhancedChatSystemDB::addUser(const std::string& userId, int socketFd, const std::string& ip) {
    std::lock_guard<std::mutex> lock(usersMutex);
    
    // 检查用户是否已在线
    if (onlineUsers.find(userId) != onlineUsers.end()) {
        return false;
    }
    
    // 尝试从数据库加载用户信息
    auto user = dbManager->getUser(userId);
    if (!user) {
        // 用户不存在，创建新用户
        user = std::make_shared<UserInfo>(userId, socketFd, ip);
        if (!dbManager->insertUser(user)) {
            std::cerr << "Failed to insert user to database: " << userId << std::endl;
            return false;
        }
    } else {
        // 更新用户连接信息
        user->socketFd = socketFd;
        user->ip = ip;
        user->status = STATUS_ONLINE;
        user->loginTime = time(nullptr);
        user->lastActiveTime = time(nullptr);
        
        if (!dbManager->updateUser(user)) {
            std::cerr << "Failed to update user in database: " << userId << std::endl;
        }
    }
    
    // 添加到内存缓存
    onlineUsers[userId] = user;
    socketToUser[socketFd] = userId;
    
    std::cout << "User added: " << userId << " from " << ip << std::endl;
    return true;
}

void EnhancedChatSystemDB::removeUser(const std::string& userId) {
    std::lock_guard<std::mutex> lock(usersMutex);
    
    auto it = onlineUsers.find(userId);
    if (it != onlineUsers.end()) {
        // 更新数据库中的用户状态为离线
        dbManager->updateUserStatus(userId, STATUS_OFFLINE);
        
        // 从socket映射中移除
        socketToUser.erase(it->second->socketFd);
        
        // 从内存缓存中移除
        onlineUsers.erase(it);
        
        std::cout << "User removed: " << userId << std::endl;
    }
}

std::shared_ptr<UserInfo> EnhancedChatSystemDB::getUser(const std::string& userId) {
    // 首先检查内存缓存
    {
        std::lock_guard<std::mutex> lock(usersMutex);
        auto it = onlineUsers.find(userId);
        if (it != onlineUsers.end()) {
            return it->second;
        }
    }
    
    // 从数据库加载
    return dbManager->getUser(userId);
}

std::vector<std::shared_ptr<UserInfo>> EnhancedChatSystemDB::getOnlineUsers() {
    std::lock_guard<std::mutex> lock(usersMutex);
    std::vector<std::shared_ptr<UserInfo>> users;
    
    for (const auto& pair : onlineUsers) {
        if (pair.second->status == STATUS_ONLINE) {
            users.push_back(pair.second);
        }
    }
    
    return users;
}

bool EnhancedChatSystemDB::updateUserStatus(const std::string& userId, UserStatus status) {
    // 更新内存缓存
    {
        std::lock_guard<std::mutex> lock(usersMutex);
        auto it = onlineUsers.find(userId);
        if (it != onlineUsers.end()) {
            it->second->status = status;
        }
    }
    
    // 更新数据库
    return dbManager->updateUserStatus(userId, status);
}

void EnhancedChatSystemDB::updateUserActivity(const std::string& userId) {
    // 更新内存缓存
    {
        std::lock_guard<std::mutex> lock(usersMutex);
        auto it = onlineUsers.find(userId);
        if (it != onlineUsers.end()) {
            it->second->lastActiveTime = time(nullptr);
        }
    }
    
    // 更新数据库（异步，避免阻塞）
    dbManager->updateUserActivity(userId);
}

// ==================== 私聊管理 ====================

std::string EnhancedChatSystemDB::startPrivateChat(const std::string& user1, const std::string& user2) {
    std::string chatId = generateChatId(user1, user2);
    
    // 检查私聊是否已存在
    auto chat = dbManager->getPrivateChat(chatId);
    if (!chat) {
        // 创建新的私聊会话
        chat = std::make_shared<PrivateChat>(user1, user2);
        if (!dbManager->insertPrivateChat(chat)) {
            std::cerr << "Failed to create private chat: " << chatId << std::endl;
            return "";
        }
        
        std::cout << "Private chat created: " << chatId << std::endl;
    }
    
    return chatId;
}

bool EnhancedChatSystemDB::sendPrivateMessage(const std::string& fromUser, const std::string& toUser, const std::string& content) {
    // 确保私聊会话存在
    std::string chatId = startPrivateChat(fromUser, toUser);
    if (chatId.empty()) {
        return false;
    }
    
    // 创建消息
    EnhancedMessage msg;
    msg.type = MSG_PRIVATE_CHAT;
    msg.messageId = generateId();
    msg.fromUser = fromUser;
    msg.toUser = toUser;
    msg.content = content;
    msg.timestamp = time(nullptr);
    msg.chatType = CHAT_PRIVATE;
    
    // 保存消息到数据库
    if (!saveMessageToDatabase(msg)) {
        std::cerr << "Failed to save private message to database" << std::endl;
        return false;
    }
    
    // 更新聊天活跃时间
    updateChatActivity(chatId);
    
    // 发送消息给接收者
    sendToUser(toUser, msg);
    
    std::cout << "Private message sent from " << fromUser << " to " << toUser << std::endl;
    return true;
}

std::shared_ptr<PrivateChat> EnhancedChatSystemDB::getPrivateChat(const std::string& user1, const std::string& user2) {
    std::string chatId = generateChatId(user1, user2);
    return dbManager->getPrivateChat(chatId);
}

std::vector<std::string> EnhancedChatSystemDB::getUserPrivateChats(const std::string& userId) {
    return dbManager->getUserPrivateChats(userId);
}

std::vector<EnhancedMessage> EnhancedChatSystemDB::getPrivateMessages(const std::string& user1, const std::string& user2, int limit, int offset) {
    return dbManager->getPrivateMessages(user1, user2, limit, offset);
}

// ==================== 群组管理 ====================

std::string EnhancedChatSystemDB::createGroup(const std::string& groupName, const std::string& ownerId, const std::string& description) {
    std::string groupId = generateId();
    auto group = std::make_shared<GroupInfo>(groupId, groupName, ownerId);
    group->description = description;
    
    // 保存到数据库
    if (!dbManager->insertGroup(group)) {
        std::cerr << "Failed to create group in database: " << groupName << std::endl;
        return "";
    }
    
    // 添加群主为成员
    if (!dbManager->addGroupMember(groupId, ownerId, ROLE_OWNER)) {
        std::cerr << "Failed to add owner to group: " << groupId << std::endl;
    }
    
    std::cout << "Group created: " << groupName << " (" << groupId << ")" << std::endl;
    return groupId;
}

bool EnhancedChatSystemDB::joinGroup(const std::string& groupId, const std::string& userId) {
    // 检查群组是否存在
    auto group = dbManager->getGroup(groupId);
    if (!group) {
        return false;
    }
    
    // 添加成员
    return dbManager->addGroupMember(groupId, userId, ROLE_MEMBER);
}

bool EnhancedChatSystemDB::leaveGroup(const std::string& groupId, const std::string& userId) {
    // 检查群组是否存在
    auto group = dbManager->getGroup(groupId);
    if (!group) {
        return false;
    }
    
    // 群主不能离开群组，只能解散
    if (group->ownerId == userId) {
        return false;
    }
    
    // 移除成员
    return dbManager->removeGroupMember(groupId, userId);
}

bool EnhancedChatSystemDB::sendGroupMessage(const std::string& groupId, const std::string& fromUser, const std::string& content) {
    // 检查群组是否存在
    auto group = dbManager->getGroup(groupId);
    if (!group) {
        return false;
    }
    
    // 检查用户是否为群成员
    auto members = dbManager->getGroupMembers(groupId);
    if (std::find(members.begin(), members.end(), fromUser) == members.end()) {
        return false;
    }
    
    // 创建群消息
    EnhancedMessage msg;
    msg.type = MSG_GROUP_CHAT;
    msg.messageId = generateId();
    msg.fromUser = fromUser;
    msg.groupId = groupId;
    msg.content = content;
    msg.timestamp = time(nullptr);
    msg.chatType = CHAT_GROUP;
    
    // 保存消息到数据库
    if (!saveMessageToDatabase(msg)) {
        std::cerr << "Failed to save group message to database" << std::endl;
        return false;
    }
    
    // 广播消息给群成员
    broadcastToGroup(groupId, msg, fromUser);
    
    std::cout << "Group message sent in " << groupId << " by " << fromUser << std::endl;
    return true;
}

std::shared_ptr<GroupInfo> EnhancedChatSystemDB::getGroup(const std::string& groupId) {
    return dbManager->getGroup(groupId);
}

std::vector<std::shared_ptr<GroupInfo>> EnhancedChatSystemDB::getUserGroups(const std::string& userId) {
    return dbManager->getUserGroups(userId);
}

std::vector<EnhancedMessage> EnhancedChatSystemDB::getGroupMessages(const std::string& groupId, int limit, int offset) {
    return dbManager->getGroupMessages(groupId, limit, offset);
}

// ==================== 消息路由 ====================

void EnhancedChatSystemDB::routeMessage(const EnhancedMessage& message) {
    switch (message.type) {
        case MSG_PRIVATE_CHAT:
            sendPrivateMessage(message.fromUser, message.toUser, message.content);
            break;
            
        case MSG_GROUP_CHAT:
            sendGroupMessage(message.groupId, message.fromUser, message.content);
            break;
            
        case MSG_JOIN_GROUP:
            joinGroup(message.groupId, message.fromUser);
            break;
            
        case MSG_LEAVE_GROUP:
            leaveGroup(message.groupId, message.fromUser);
            break;
            
        default:
            std::cerr << "Unknown message type: " << static_cast<int>(message.type) << std::endl;
            break;
    }
}

void EnhancedChatSystemDB::sendToUser(const std::string& userId, const EnhancedMessage& message) {
    std::shared_ptr<UserInfo> user;
    {
        std::lock_guard<std::mutex> lock(usersMutex);
        auto userIt = onlineUsers.find(userId);
        if (userIt == onlineUsers.end() || userIt->second->status == STATUS_OFFLINE) {
            return; // 用户不在线
        }
        user = userIt->second;
    }
    
    // 发送消息到用户的socket
    std::string data = message.serialize();
    send(user->socketFd, data.c_str(), data.length(), 0);
    
    // 更新用户活跃时间
    updateUserActivity(userId);
}

void EnhancedChatSystemDB::broadcastToGroup(const std::string& groupId, const EnhancedMessage& message, const std::string& excludeUser) {
    // 获取群成员列表
    auto members = dbManager->getGroupMembers(groupId);
    
    // 向群组所有在线成员发送消息（除了排除的用户）
    for (const std::string& memberId : members) {
        if (memberId != excludeUser && isUserOnline(memberId)) {
            sendToUser(memberId, message);
        }
    }
}

// ==================== 工具方法 ====================

std::string EnhancedChatSystemDB::generateId() {
    // 生成唯一ID（时间戳 + 随机数）
    static std::random_device rd;
    static std::mt19937 gen(rd());
    static std::uniform_int_distribution<> dis(1000, 9999);
    
    auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();
    
    return std::to_string(now) + "_" + std::to_string(dis(gen));
}

std::string EnhancedChatSystemDB::generateChatId(const std::string& user1, const std::string& user2) {
    // 按字典序排序确保聊天ID的唯一性
    if (user1 < user2) {
        return user1 + "_" + user2;
    } else {
        return user2 + "_" + user1;
    }
}

bool EnhancedChatSystemDB::isUserOnline(const std::string& userId) {
    std::lock_guard<std::mutex> lock(usersMutex);
    auto userIt = onlineUsers.find(userId);
    return (userIt != onlineUsers.end() && userIt->second->status == STATUS_ONLINE);
}

// ==================== 数据同步方法 ====================

bool EnhancedChatSystemDB::loadUserToCache(const std::string& userId) {
    auto user = dbManager->getUser(userId);
    if (!user) {
        return false;
    }
    
    std::lock_guard<std::mutex> lock(usersMutex);
    onlineUsers[userId] = user;
    if (user->socketFd > 0) {
        socketToUser[user->socketFd] = userId;
    }
    
    return true;
}

void EnhancedChatSystemDB::syncOnlineUsersToDatabase() {
    std::lock_guard<std::mutex> lock(usersMutex);
    
    for (const auto& pair : onlineUsers) {
        dbManager->updateUser(pair.second);
    }
    
    std::cout << "Synced " << onlineUsers.size() << " online users to database" << std::endl;
}

void EnhancedChatSystemDB::cleanupOfflineUsers() {
    std::lock_guard<std::mutex> lock(usersMutex);
    
    auto it = onlineUsers.begin();
    while (it != onlineUsers.end()) {
        if (it->second->status == STATUS_OFFLINE) {
            socketToUser.erase(it->second->socketFd);
            it = onlineUsers.erase(it);
        } else {
            ++it;
        }
    }
}

// ==================== 统计信息 ====================

int EnhancedChatSystemDB::getUserMessageCount(const std::string& userId) {
    return dbManager->getUserMessageCount(userId);
}

int EnhancedChatSystemDB::getGroupMessageCount(const std::string& groupId) {
    return dbManager->getGroupMessageCount(groupId);
}

std::vector<EnhancedMessage> EnhancedChatSystemDB::getRecentMessages(const std::string& userId, int limit) {
    return dbManager->getRecentMessages(userId, limit);
}

// ==================== 私有辅助方法 ====================

bool EnhancedChatSystemDB::saveMessageToDatabase(const EnhancedMessage& message) {
    return dbManager->insertMessage(message);
}

void EnhancedChatSystemDB::updateChatActivity(const std::string& chatId) {
    dbManager->updatePrivateChatActivity(chatId);
}

std::shared_ptr<UserInfo> EnhancedChatSystemDB::getUserFromCache(const std::string& userId) {
    std::lock_guard<std::mutex> lock(usersMutex);
    auto it = onlineUsers.find(userId);
    return (it != onlineUsers.end()) ? it->second : nullptr;
}

void EnhancedChatSystemDB::removeUserFromCache(const std::string& userId) {
    std::lock_guard<std::mutex> lock(usersMutex);
    auto it = onlineUsers.find(userId);
    if (it != onlineUsers.end()) {
        socketToUser.erase(it->second->socketFd);
        onlineUsers.erase(it);
    }
}